package sharewithus.content.dao.cacheimpl;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import sharewithus.content.dao.IFeedRelationshipCache;
import sharewithus.content.dao.cacheimpl.encoder.BeanEncoder;
import sharewithus.content.dto.Feed;
import sharewithus.content.dto.FeedRelationship;

public class FeedRelationshipCacheImpl implements IFeedRelationshipCache {

	private static final String JEDIS_CHARSET = "UTF-8";

	private static final String REDIS_KEY_SUBCRIBER_PREX = "feedfr:";

	private ObjectMapper mapper = new ObjectMapper();

	@Autowired
	@Qualifier("shardedJedisPool")
	private ShardedJedisPool jedisMgr;

	@Autowired
	private BeanEncoder<FeedRelationship> feedRelationshipEncoder;
	
	
	

	public List<FeedRelationship> getSubscribedFeeds(String subscriberId) {
		return getSubscribedFeeds(subscriberId, -1, -1);

	}
	
	public List<FeedRelationship> getSubscribedFeeds(String subscriberId, int pageSize, int pageNumber) {
		ShardedJedis jedis = null;
		List<FeedRelationship> frList = new LinkedList<FeedRelationship>();
		String frListKey = REDIS_KEY_SUBCRIBER_PREX + subscriberId;
		
		List<String> frJsons = null;
		try{
		if (pageSize >= 0 && pageNumber >= 0) {
			long savedSize = jedis.llen(frListKey);

			long startNumber = pageSize * (pageNumber - 1);
			long endNumber = pageSize * pageNumber - 1;

			if (savedSize > endNumber) {
				frJsons = jedis.lrange(frListKey, startNumber,
						endNumber);
			}
			if (startNumber <= savedSize && savedSize <= endNumber) {
				frJsons = jedis.lrange(frListKey, startNumber, -1);
			} else {
				// feedJsons = jedis.lrange(feedListKey, 0, -1);
			}
		} else {
			frJsons = jedis.lrange(frListKey, 0, -1);
		}
		}finally{
			if (jedis != null)
				jedisMgr.returnResource(jedis);
		}
		
		Iterator<String> iter = frJsons.iterator();
		String frJson = null;
		while (iter.hasNext()) {
			frJson = iter.next();
			if (frJson != null && !"".equals(frJson)) {
				frList.add(feedRelationshipEncoder.parseJson(frJson));
			}
		}
		return frList;
		
	}
	

	public void saveSubscriberFeeds(String subscriberId, Feed feed) {
		String frListKey = REDIS_KEY_SUBCRIBER_PREX + subscriberId;
		ShardedJedis jedis = null;
		try {
			jedis = jedisMgr.getResource();
			FeedRelationship fr = new FeedRelationship();
			fr.setFeedId(feed.getFeedId());
			fr.setFeedOwnerId(feed.getOwnerId());
			fr.setSubscribeUserId(subscriberId);

			jedis.lpush(frListKey, feedRelationshipEncoder.getFrJson(fr));
		} finally {
			if (jedis != null)
				jedisMgr.returnResource(jedis);
		}

	}

	public List<FeedRelationship> getOwnerFeedPage(String ownerId) {
		return getOwnerFeedPage(ownerId, -1, -1);
	}

	public List<FeedRelationship> getOwnerFeedPage(String ownerId,
			int pageSize, int pageNumber) {
		String feedListKey = REDIS_KEY_SUBCRIBER_PREX + ownerId;
		ShardedJedis jedis = null;
		List<FeedRelationship> frs = new LinkedList<FeedRelationship>();
		try {
			jedis = jedisMgr.getResource();

			List<String> feedJsons = new LinkedList<String>();
			if (pageSize >= 0 && pageNumber >= 0) {
				long savedSize = jedis.llen(feedListKey);

				long startNumber = pageSize * (pageNumber - 1);
				long endNumber = pageSize * pageNumber - 1;

				if (savedSize > endNumber) {
					feedJsons = jedis.lrange(feedListKey, startNumber,
							endNumber);
				}
				if (startNumber <= savedSize && savedSize <= endNumber) {
					feedJsons = jedis.lrange(feedListKey, startNumber, -1);
				} else {
					// feedJsons = jedis.lrange(feedListKey, 0, -1);
				}
			} else {
				feedJsons = jedis.lrange(feedListKey, 0, -1);
			}

			Iterator<String> iter = feedJsons.iterator();

			String feedJson;
			while (iter.hasNext()) {
				feedJson = iter.next();
				frs.add(feedRelationshipEncoder.parseJson(feedJson));
			}
			jedisMgr.returnResource(jedis);
		} finally {
			if (jedis != null)
				jedisMgr.returnResource(jedis);
		}
		return frs;
	}

	public void saveOwnerFeed(Feed feed) {
		FeedRelationship fr = new FeedRelationship();
		fr.setFeedId(feed.getFeedId());
		String feedListKey = REDIS_KEY_SUBCRIBER_PREX + feed.getOwnerId();
		ShardedJedis jedis = null;
		try {
			jedis = jedisMgr.getResource();
			jedis.lpush(feedListKey, feedRelationshipEncoder.getFrJson(fr));
		} finally {
			if (jedis != null)
				jedisMgr.returnResource(jedis);
		}
		jedisMgr.returnResource(jedis);
		// jedis.disconnect();
	}

}
